/*
 * @ author madman 
 * @ use Webhook
 */
const CountryModel = require('../../models/nexmo/country.model');
import { parsePhoneNumberFromString as parseMobile } from 'libphonenumber-js/mobile'
const CallrecordsModel = require('../../models/nexmo/callrecords.model');
const clientModel = require('../../models/nexmo/client.model');
const PriceModel = require('../../models/nexmo/price.model');
const PriceOutModel = require('../../models/nexmo/priceout.model');
const Utils = require('../utils');
const nexmo = require('../utils/nexmo');
const Nexmo = require('nexmo')
const NexmoCli = new Nexmo({
  apiKey: '289e6a50',
  apiSecret: '28xQbIsYyTCx4Wb5',
  applicationId: '16763a08-8c51-44a9-9933-1e7a5716c1d7',
  privateKey:process.cwd()+'/private.key'
})
console.log()
class Webhook {

  // 获取 JWT token验证
    async GetToken(ctx) {
      const aclPaths = {
        "paths": {
          "/v1/users/**": {},
          "/v1/conversations/**": {},
          "/v1/sessions/**": {},
          "/v1/devices/**": {},
          "/v1/image/**": {},
          "/v3/media/**": {},
          "/v1/applications/**": {},
          "/v1/push/**": {},
          "/v1/knocking/**": {}
        }
      }
      var token = Nexmo.generateJwt(process.cwd()+'/private.key', {
        application_id: "16763a08-8c51-44a9-9933-1e7a5716c1d7",
        sub: ctx.query.user,
        //expire in 24 hours 过期
        exp: Math.round(new Date().getTime()/1000)+86400,
        acl: aclPaths
      })
      return ctx.success({ msg:'获取成功', data: {token: token}});
    }
    // 监听回调
    async Event(ctx) {
      // 记录本次通话记录
        var eventQuery = {
          status: ctx.query.status,
          uuid: ctx.query.uuid,
          end_time: ctx.query.end_time,
          start_time:  ctx.query.start_time,
          duration: ctx.query.duration || '0',
          conversation_uuid: ctx.query.conversation_uuid
        }
        // 获取当前的通话记录
        var $callRecords = await CallrecordsModel.findOne({'conversation_uuid': ctx.query.conversation_uuid},  { uuid: 1, price: 1, inPrice: 1, outPrice: 1, ioType: 1});
        // 通话结束后如果有返回通话费用就更新
        if (ctx.query.status === 'completed' && ctx.query.from && ctx.query.to && ctx.query.price !=='0' && parseFloat(ctx.query.price) > 0) {
            var time = Utils.decimal(parseFloat(ctx.query.duration), 60, 'div') // 不足1分钟按分钟算
            console.log('time___'+ctx.query.duration,time)
            var diffTime = time < 1 ? 1: time.toString().indexOf('.') > 0 ? Math.ceil(time) :time;
            console.log('diffTime____'+diffTime)
            console.log('ceil___' + Math.ceil(1.09))
            var _inPrice = parseFloat($callRecords.inPrice) || 0
            var _outPrice = parseFloat($callRecords.outPrice) || 0
            var _decimalPrice = Utils.decimal(parseFloat($callRecords.price), parseFloat(ctx.query.price), 'add') + ''
            var _profits = null
            if($callRecords.ioType === '1') {
              _profits = Utils.decimal(diffTime, _inPrice, 'mul')
            } else if($callRecords.ioType === '2' || $callRecords.ioType === '3' || $callRecords.ioType === '4') {
              _profits = Utils.decimal(diffTime, _outPrice, 'mul') 
            }
            eventQuery.callHarges = _profits   // 当前通话费用 价格 * 时间 
            eventQuery.duration =  ctx.query.duration || '0'
            eventQuery.profits = Utils.decimal(_profits, parseFloat(ctx.query.price), 'sub')
            console.log('profits_____'+_profits, parseFloat(ctx.query.price), _profits - parseFloat(ctx.query.price))
            eventQuery.direction = ctx.query.direction
            eventQuery.rate = ctx.query.rate
            // 如本次通话有2个UUID 取数据库的第一个链路的price + 第二个链路的price
            eventQuery.price = $callRecords && parseFloat($callRecords.price) > 0 ?_decimalPrice : ctx.query.price 
            //通过conversation_uuid取来电虚拟号，再通过虚拟号查询当前帐户余额，再去计算更新
            const callrecords = await CallrecordsModel.findOne({conversation_uuid: ctx.query.conversation_uuid}, {_id: 0,msisdn: 1});
            if (callrecords) {
              const call = await clientModel.findOne({ msisdn: callrecords.msisdn }, {_id : 0, remainingMoney : 1})
              // 更新虚拟号余额
              if (call) {
                var _price = Utils.decimal(parseFloat(call.remainingMoney), parseFloat(_profits), 'sub') + '' 
                await clientModel.updateOne({
                   msisdn: ctx.query.direction === 'outbound' ? ctx.query.from:  ctx.query.to
                },{ 
                   $set: {
                     remainingMoney: _price
                    }
                 });
              }
            }
        }
        await CallrecordsModel.updateOne({'conversation_uuid': ctx.query.conversation_uuid},  { $set: eventQuery });
        return ctx.success({ msg:'Event'});
    }
    // answer URL 
    async Answer(ctx) {
      var NCCO = null
      var country = null;
      var client = null
      var callForwarding = null // 记录呼叫转移
      var priceOut = {}
      var isNumberOut= ctx.query.to.indexOf('-') > -1 // 如果是C端传来的值带有中横线
      var _nTo = ctx.query.to.split('-')
      var toNumber = isNumberOut? _nTo : ctx.query.from
      var _phoneNumber = null
      var phoneNumber = null
      var options = {
        conversation_uuid: ctx.query.conversation_uuid
      }
      var _clientModel = await clientModel.findOne({'msisdn' : (isNumberOut? _nTo[0] + _nTo[1]: ctx.query.to)}) || {}
      console.log('clientModel___'+_clientModel.callForwarding)
      // 通过C端传来的值判断入站还是出站
      if (isNumberOut) {
        _phoneNumber = parseMobile('+' + toNumber[0]+ toNumber[1])
        options.to = toNumber[1]
        options.msisdn = toNumber[2]
        options.callType = 'outbound'
        options.dialingPrefix = toNumber[0]
        // 设置当前通话类型用于利润计算
        if (_phoneNumber.getType() === 'MOBILE' || _phoneNumber.getType() === 'FIXED_LINE') {
          options.ioType = '2'
          options.fromTelType = _phoneNumber.getType()
        } else {
          options.fromTelType = 'NEXMO'
          options.ioType = '3'
        }
      } else {
        phoneNumber = parseMobile('+' + toNumber)
        var toPhoneNumber = parseMobile('+' + ctx.query.to)
        options.to = phoneNumber.nationalNumber
        options.msisdn = ctx.query.to
        options.callType = 'inbound'
        options.dialingPrefix = phoneNumber.countryCallingCode

        options.ioType = '1'
        options.fromTelType = phoneNumber.getType()
      }
       // 如果是呼出就取form的号国家，反之取to国家
      var _toM = isNumberOut ? toNumber[0]+ toNumber[1] : ctx.query.to;
      var $phoneNumber = parseMobile('+' + _toM)
      country = $phoneNumber.country
      console.log(_toM, ctx.query.from, $phoneNumber.country)
      // 查询当前虚拟号绑定的哪个用户
      if (options.msisdn) {
        client = await clientModel.findOne({'msisdn' : options.msisdn})
        console.log('user_' + client.user)
        priceOut = await PriceOutModel.findOne({'msisdn' : options.msisdn, countryCode: country}, {mobileOutPrice: 1, telOutPrice: 1})
      }
      console.log('priceOut----' + options.to + '--' + country)
       // 根据国家代码查询国家名称
      var Country = await CountryModel.findOne({countryCode: country})
      var Price = await PriceModel.findOne({countryCode: country}, {inPrice: 1, mobileOutPrice: 1, telOutPrice: 1})
      if (Price) {
        // 如果查询当前虚拟号有设置呼出价格
        if (options.fromTelType === 'MOBILE' && options.callType === 'outbound') {
          options.outPrice = (priceOut && priceOut.mobileOutPrice) || Price.mobileOutPrice
        } else if(options.fromTelType === 'FIXED_LINE' && options.callType === 'outbound') { 
          options.outPrice = (priceOut && priceOut.telOutPrice) ||  Price.telOutPrice
        } else if(options.fromTelType = 'NEXMO' && options.callType === 'outbound') {
          options.outPrice = Price.mobileOutPrice
        } else {
          options.inPrice = (priceOut && priceOut.inPrice) ||  Price.inPrice
        }
      }
      console.log('msisdn: '+options.msisdn + '____to:' + options.to)
      console.log('outPrice: '+options.outPrice + '____inPrice:' + options.inPrice, options.fromTelType, options.callType)
      if (Country) {
        if (client) {
          options.country = client.country
        }
        options.countryName = Country.countryName
      }
      //查询当前虚拟号是否有呼叫转移功能
      if (_clientModel.callForwarding) {
        console.log('转移到哪:'+options.msisdn, options.to, toNumber[1], toNumber[2])
        // options.msisdn = toNumber[0] + toNumber[1]
        options.ioType = '4'
        options.callType = 'callforwarding'
        var _parseMobile = parseMobile('+' + _clientModel.callForwarding)
        var _parsePriceModel = await PriceModel.findOne({countryCode: _parseMobile.country}, { inPrice: 1, mobileOutPrice: 1, mobileOutPrice: 1})
        var inPrice = client.inPrice ||  Price.inPrice
        // 呼入价格 + 呼出价格（转移国家号）
        options.mobileOutPrice = _parsePriceModel.mobileOutPrice
        console.log('呼入价格:'+_parsePriceModel.mobileOutPrice , '呼入价格:' + inPrice, '国家代码:' + _parseMobile.country)
        options.outPrice = Utils.decimal(parseFloat(inPrice), parseFloat(_parsePriceModel.mobileOutPrice), 'add')
      }
      
      CallrecordsModel.create(options); // 新建通话记录
      console.log('转移: '+_clientModel.callForwarding)
      // 呼叫转移
      if (isNumberOut && !_clientModel.callForwarding) {
        console.log('num_'+ toNumber[0] + toNumber[1] + '__' + toNumber[2])
        NCCO = [{
              "action": "connect",
              "eventUrl": ["https://afly-server.juney.cn/event"],
              "eventMethod": "GET",
              "timeout": 100,
              "from": toNumber[2],
              "endpoint": [{
                  "type": "phone",
                  "number": toNumber[0] + toNumber[1]
              }]
          }]
      } else {
        // 如果是呼入且设置了呼叫转移
        if (_clientModel.callForwarding) {
          console.log('callForwarding1——'+ _clientModel.callForwarding +'___'+ ctx.query.from);
          console.log('callForwarding2——'+isNumberOut? toNumber[0] + toNumber[1] :  options.msisdn, _clientModel.callForwarding)
          NCCO = [{
            "action": "connect",
            "eventUrl": ["https://afly-server.juney.cn/event"],
            "eventMethod": "GET",
            "timeout": 100,
            "from":  options.msisdn,
            "endpoint": [{
                "type": "phone",
                "number": _clientModel.callForwarding
            }]
          }]
        } else {
          console.log('接电话_'+ callForwarding +'___'+ ctx.query.from, client.user)
          //接电话返回的NCCO
          NCCO = [{
            "action": "connect",
            "from": ctx.query.from,
            "endpoint": [{
                "type": "app",
                "user": client && client.user // 从客户列表里取user
            }]
          }]
        }
      }
      return ctx.json({ data : NCCO })
    }
}

export default new Webhook;